package ch.fusun.baron.clientapp.login;

import java.util.LinkedList;
import java.util.List;

import org.eclipse.core.runtime.CoreException;
import org.eclipse.core.runtime.IConfigurationElement;
import org.eclipse.core.runtime.Platform;
import org.eclipse.jface.dialogs.IDialogConstants;
import org.eclipse.jface.dialogs.TitleAreaDialog;
import org.eclipse.swt.SWT;
import org.eclipse.swt.events.ModifyEvent;
import org.eclipse.swt.events.ModifyListener;
import org.eclipse.swt.events.SelectionAdapter;
import org.eclipse.swt.events.SelectionEvent;
import org.eclipse.swt.layout.GridData;
import org.eclipse.swt.layout.GridLayout;
import org.eclipse.swt.widgets.Composite;
import org.eclipse.swt.widgets.Control;
import org.eclipse.swt.widgets.Label;
import org.eclipse.swt.widgets.Shell;
import org.eclipse.swt.widgets.Text;

import ch.fusun.baron.client.rmi.ClientService;
import ch.fusun.baron.clientapp.messages.Messages;
import ch.fusun.baron.core.rmi.User;

/**
 * Dialog to create an account
 */
public class CreateAccountDialog extends TitleAreaDialog {

	private static String ACCOUNTPROPERTY_ID = "ch.fusun.baron.clientapp.accountproperty"; //$NON-NLS-1$
	private static String PROPERTY = "property"; //$NON-NLS-1$

	private String username;
	private String password;
	private final ClientService gameClient;
	private final List<AccountProperty> accountProperties = new LinkedList<AccountProperty>();

	/**
	 * Constructor
	 * 
	 * @param parentShell
	 *            The parent shell
	 * @param gameClient2
	 *            The starter instance
	 */
	public CreateAccountDialog(Shell parentShell, ClientService gameClient2) {
		super(parentShell);
		this.gameClient = gameClient2;
		findAccountProperties();
	}

	private void findAccountProperties() {
		IConfigurationElement[] config = Platform.getExtensionRegistry()
				.getConfigurationElementsFor(ACCOUNTPROPERTY_ID);
		try {
			for (IConfigurationElement e : config) {
				accountProperties.add((AccountProperty) e
						.createExecutableExtension(PROPERTY));
			}
		} catch (CoreException e) {
			e.printStackTrace();
		}
	}

	@Override
	protected Control createDialogArea(Composite parent) {
		Composite area = new Composite(parent, SWT.NONE);
		area.setLayout(new GridLayout(2, false));
		area.setLayoutData(new GridData(SWT.FILL, SWT.FILL, true, true));

		new Label(area, SWT.NONE)
				.setText(Messages.CreateAccountDialog_UserName);
		final Text usernameText = new Text(area, SWT.BORDER);
		usernameText
				.setLayoutData(new GridData(SWT.FILL, SWT.NONE, true, false));
		usernameText.addModifyListener(new ModifyListener() {

			@Override
			public void modifyText(ModifyEvent e) {
				username = usernameText.getText();
			}
		});

		new Label(area, SWT.NONE)
				.setText(Messages.CreateAccountDialog_Password);
		final Text passwordText = new Text(area, SWT.BORDER | SWT.PASSWORD);
		passwordText
				.setLayoutData(new GridData(SWT.FILL, SWT.NONE, true, false));
		passwordText.addModifyListener(new ModifyListener() {

			@Override
			public void modifyText(ModifyEvent e) {
				password = passwordText.getText();
			}
		});

		for (AccountProperty property : accountProperties) {
			property.createUi(area);
		}

		return area;
	}

	@Override
	protected void createButtonsForButtonBar(Composite parent) {
		super.createButtonsForButtonBar(parent);
		getButton(IDialogConstants.OK_ID).addSelectionListener(
				new SelectionAdapter() {
					@Override
					public void widgetSelected(SelectionEvent e) {
						gameClient.createUser(new User(username, password));
						for (AccountProperty property : accountProperties) {
							gameClient.execute(property.getCommand(gameClient
									.getUser()));
						}
					}
				});
	}

	/**
	 * @return The user name
	 */
	public String getUsername() {
		return username;
	}

	/**
	 * @return The password
	 */
	public String getPassword() {
		return password;
	}

}
